package core

import (
	"errors"
	"fmt"
	"github.com/jinzhu/gorm"
)

// 数据库引擎管理器
type DBEngineManager struct {
	DBEngine map[string]*gorm.DB
}

// 数据库配置
type DBConfig struct {
	DbType          string
	DbName          string
	Charset         string
	Username        string
	Password        string
	Host            string
	MaxIdleConnects int
	MaxOpenConnects int
}

// 初始化DB管理器
func NewDBEngineManager() (*DBEngineManager, error) {
	dbTree := make(map[string]*gorm.DB)
	DBEngineManager := &DBEngineManager{DBEngine: dbTree}
	databaseSettingParams := DatabaseSetting
	defaultDBEngine, err := DBEngineManager.NewDBEngine(DBConfig{
		DbType:          databaseSettingParams.DBType,
		DbName:          databaseSettingParams.DBName,
		Charset:         databaseSettingParams.Charset,
		Username:        databaseSettingParams.Username,
		Password:        databaseSettingParams.Password,
		Host:            databaseSettingParams.Host,
		MaxIdleConnects: databaseSettingParams.MaxIdleConns,
		MaxOpenConnects: databaseSettingParams.MaxIdleConns,
	})
	if err != nil {
		return nil, err
	}
	DBEngineManager.DBEngine["default"] = defaultDBEngine
	return DBEngineManager, nil
}

// 加入一个新的数据库链接
func (db *DBEngineManager) AddEngine(dbMapName string, config DBConfig) error {
	newDBEngine, err := db.NewDBEngine(config)
	if err != nil {
		return err
	}
	db.DBEngine[dbMapName] = newDBEngine
	return nil
}

// 移除数据库引擎
func (db *DBEngineManager) RemoveEngine(dbMapName string) error {
	if _, err := db.DBEngine[dbMapName]; !err {
		return errors.New(fmt.Sprintf("%s db engine not exist", dbMapName))
	}
	delete(db.DBEngine, dbMapName)
	return nil
}

// 引擎是否存在
func (db *DBEngineManager) ExistEngine(dbName string) bool {
	if _, err := db.DBEngine[dbName]; err {
		return false
	}
	return true
}

// 重置数据库引擎
func (db *DBEngineManager) ReSetEngine(dbName string, config DBConfig) error {
	if _, err := db.DBEngine[dbName]; !err {
		return errors.New(fmt.Sprintf("%s not exist", dbName))
	}
	dbEngine, err := db.NewDBEngine(config)
	if err != nil {
		return err
	}
	db.DBEngine[dbName] = dbEngine
	return nil
}

// 获取一个新的DB引擎
func (db *DBEngineManager) NewDBEngine(dbConfig DBConfig) (*gorm.DB, error) {
	dbModel, err := gorm.Open(dbConfig.DbType, fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=%s",
		dbConfig.Username,
		dbConfig.Password,
		dbConfig.Host,
		dbConfig.DbName,
		dbConfig.Charset,
	))
	if err != nil {
		return nil, err
	}
	if ServerSetting.RunMode == "debug" {
		dbModel.LogMode(true)
	}
	dbModel.SingularTable(true)
	dbModel.DB().SetMaxIdleConns(dbConfig.MaxIdleConnects)
	dbModel.DB().SetMaxOpenConns(dbConfig.MaxOpenConnects)
	return dbModel, nil
}

func (db *DBEngineManager) DefaultDBEngine() (*gorm.DB, error) {
	if _, err := db.DBEngine["default"]; !err {
		return nil, errors.New("default DBEngine not exist")
	}
	return db.DBEngine["default"], nil
}
